package com.example.lt.service.audit;

import com.example.lt.config.QiNiuConfig;
import com.example.lt.constant.AuditStatus;
import com.example.lt.entity.Setting;
import com.example.lt.entity.json.*;
import com.example.lt.entity.response.AuditResponse;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.util.StringMap;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Author 小涛Tao
 * @Date: 2024/08/01/14:44
 * version 1.0 注释：图片内容审核
 **/
@Service
public class ImageAuditService extends AbstractAuditService<String, AuditResponse> {

    // 图片的内容审核 API 地址
    static String imageUlr = "http://ai.qiniuapi.com/v3/image/censor";

    // 根据官方文档的示例来自定义请求体
    static String imageBody = "{\n" +
            "    \"data\": {\n" +
            "        \"uri\": \"${url}\"\n" +
            "    },\n" +
            "    \"params\": {\n" +
            "        \"scenes\": [\n" +
            "            \"pulp\",\n" +
            "            \"terror\",\n" +
            "            \"politician\"\n" +
            "        ]\n" +
            "    }\n" +
            "}";

    @Override
    public AuditResponse audit(String url) {
        AuditResponse auditResponse = new AuditResponse();
        auditResponse.setAuditStatus(AuditStatus.SUCCESS);

        // 审核开关，在系统表中 0：表示关闭  1：表示开启
        if (!isNeedAudit()) {
            return auditResponse;
        }

        try {
            // 如果 url 中不包含对象存储外链接域名，则拼接上这个域名
            if (!url.contains(QiNiuConfig.CNAME)) {
                // 对 url 进行 URL 编码，编码方式为 "utf-8" ，然后在把 encode() 方法返回的字符串中的 "+" 都替换成 "%20"
                String encodedFileName = URLEncoder.encode(url, "utf-8").replace("+", "%20");
                // 通过 format() 方法将 QiNiuConfig.CNAME 和 encodedFileName 拼接起来。方法第一个参数中的 %s 表示字符串，%d 表示整数
                url = String.format("%s/%s", QiNiuConfig.CNAME, encodedFileName);
            }
            url = appendUUID(url);

            String body = imageBody.replace("${url}", url); // 把自定义请求体中的 $url 替换成 url 参数
            String method = "POST";
            // 获取token，这个token只能用于请求 imageUlr ，且请求方法是形参 method 真实的方法，请求体也是必须是形参 body 一样，还有内容类型 contentType
            final String token = qiNiuConfig.getToken(imageUlr, method, body, contentType);
            StringMap header = new StringMap();
            header.put("Host", "ai.qiniuapi.com");
            header.put("Authorization", token); // 设置 Authorization 为包含认证信息的 token
            header.put("Content-Type", contentType);
            Configuration cfg = new Configuration(Region.region2());
            final Client client = new Client(cfg);
            Response response = client.post(imageUlr, body.getBytes(), header, contentType);

            // 获取响应的详细信息并按照 "\n" 进行分割，然后获取第三部分，因为图片审核结果中的 result 是第三部分
            // 然后通过 objectMapper 将字符串转换成 Map 对象
            final Map map = objectMapper.readValue(response.getInfo().split("\n")[2], Map.class);

            // 将 map 中 key 为 "result" 的值转换成 ResultChildJson.class 类型的对象
            // 然后创建 BodyJson 和 ResultJson 来封装 ResultChildJson 作为参数来调用 audit 方法
            final ResultChildJson result = objectMapper.convertValue(map.get("result"), ResultChildJson.class);
            final BodyJson bodyJson = new BodyJson();
            final ResultJson resultJson = new ResultJson();
            resultJson.setResultChile(result);
            bodyJson.setResult(resultJson);

            // 查询系统配置表中的唯一一条记录，记录系统各种参数的
            final Setting setting = settingService.getById(1);
            // 获取系统表中的审核规则，并通过 objectMapper 将其转换成对应类型的对象，settingScoreRule 是系统设置的审核力度
            final SettingScoreJson settingScoreRule = objectMapper.convertValue(setting.getAuditPolicy(), SettingScoreJson.class);
            final List<ScoreJson> auditRule = Arrays.asList(settingScoreRule.getManualScore(), settingScoreRule.getPassScore(), settingScoreRule.getSuccessScore());

            // 调用审核方法
            auditResponse = audit(auditRule, bodyJson);
            return auditResponse;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return auditResponse;
    }

}
